<!--
/**
 * author: vformAdmin
 * email: vdpadmin@163.com
 * date: 2021.08.18
 * remark: 如果要分发VForm源码，需在本文件顶部保留此文件头信息！！
 */
-->

<template>
  <el-container class="main-container full-height">
    <el-header class="main-header">
      <div class="float-left main-title">
        <!-- 标题-->
        <span class="bold"
          ><svg-icon icon-class="back" />
          {{ i18nt("application.productTitle") }}</span
        >
      </div>
      <div class="float-right external-link">
        <el-button
          v-if="showToolButton('importJsonButton')"
          type="text"
          @click="importJson"
        >
          {{ i18nt("designer.toolbar.importJson") }}</el-button
        >
        <el-button
          v-if="showToolButton('exportJsonButton')"
          type="text"
          @click="exportJson"
        >
          {{ i18nt("designer.toolbar.exportJson") }}</el-button
        >
        <!-- 预览  :title="i18nt('designer.toolbar.preView')" -->
        <el-button class="btn-size" type="plain" @click="previewForm()">
          {{ i18nt("designer.toolbar.preView") }}
          <svg-icon icon-class="pre-view"
        /></el-button>
        <!-- 全屏  class="btn-size" :title="i18nt('designer.toolbar.fullScreen')"-->
        <el-button
          type="plain"
          @click="handleFullScreen()"
          :class="fullscreen ? 'Bigbtn-size' : 'btn-size'"
        >
          {{
            this.fullscreen
              ? i18nt("designer.toolbar.exitFullSreen")
              : i18nt("designer.toolbar.fullScreen")
          }}
          <svg-icon icon-class="full-screen"
        /></el-button>
        <!-- 保存  :title="i18nt('designer.toolbar.save')"-->
        <el-button
          class="btn-size preserve"
          type="plain"
          :style="{ color: '#fff' }"
        >
          {{ i18nt("designer.toolbar.save") }}
          <svg-icon icon-class="save"
        /></el-button>
        <!--退出 :title="i18nt('designer.toolbar.exit')"-->
        <el-button type="plain">
          {{ i18nt("designer.toolbar.exit") }}
        </el-button>
        <toolbar-panel :designer="designer" ref="toolbarRef"> </toolbar-panel>
        <!-- 中/英文 -->
        <!-- <el-dropdown
          v-if="showLink('languageMenu')"
          :hide-timeout="2000"
          @command="handleLanguageChanged"
        >
          <span class="el-dropdown-link"
            >{{ curLangName }}<i class="el-icon-arrow-down el-icon--right"></i
          ></span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="zh-CN">{{
              i18nt("application.zh-CN")
            }}</el-dropdown-item>
            <el-dropdown-item command="en-US">{{
              i18nt("application.en-US")
            }}</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown> -->
        <!-- <a
          v-if="showLink('externalLink')"
          href="javascript:void(0)"
          @click="(ev) => openUrl(ev, gitUrl)"
          target="_blank"
          ><svg-icon icon-class="github" />{{ i18nt("application.github") }}</a
        > -->
        <!-- 文档 -->
        <!-- <a
          v-if="showLink('externalLink')"
          href="javascript:void(0)"
          @click="(ev) => openUrl(ev, docUrl)"
          target="_blank"
          ><svg-icon icon-class="document" />{{
            i18nt("application.document")
          }}</a
        > -->
        <!-- 技术微信群 -->
        <!-- <a
          v-if="showLink('externalLink')"
          href="javascript:void(0)"
          @click="(ev) => openUrl(ev, chatUrl)"
          target="_blank"
          >{{ i18nt("application.qqGroup") }}</a
        > -->
        <!-- 订阅Pro -->
        <!-- <a
          v-if="showLink('externalLink')"
          href="javascript:void(0)"
          @click="(ev) => openUrl(ev, subScribeUrl)"
          target="_blank"
        >
          {{ i18nt("application.subscription")
          }}<i class="el-icon-top-right"></i
        ></a> -->
      </div>
    </el-header>
    <!-- 主体 -->
    <el-container>
      <!-- 左侧 -->
      <el-aside class="side-panel">
        <widget-panel :designer="designer" />
      </el-aside>
      <!-- 中间 -->
      <el-container class="center-layout-container">
        <!-- <el-header class="toolbar-header"> -->

        <!-- </el-header> -->
        <el-main class="form-widget-main">
          <el-scrollbar
            class="container-scroll-bar"
            :style="{ height: scrollerHeight }"
          >
            <v-form-widget
              :designer="designer"
              :form-config="designer.formConfig"
              ref="formRef"
            >
            </v-form-widget>
          </el-scrollbar>
        </el-main>
      </el-container>
      <!-- 右侧 -->
      <el-aside>
        <setting-panel
          :designer="designer"
          :selected-widget="designer.selectedWidget"
          :form-config="designer.formConfig"
        />
      </el-aside>
    </el-container>
    <!-- 导入json -->
    <el-dialog
      :title="i18nt('designer.toolbar.importJson')"
      :visible.sync="showImportJsonDialogFlag"
      v-if="showImportJsonDialogFlag"
      :show-close="true"
      class="small-padding-dialog"
      center
      v-dialog-drag
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :destroy-on-close="true"
    >
      <el-alert
        type="info"
        :title="i18nt('designer.hint.importJsonHint')"
        show-icon
        class="alert-padding"
      ></el-alert>
      <code-editor
        :mode="'json'"
        :readonly="false"
        v-model="importTemplate"
      ></code-editor>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="doJsonImport">
          {{ i18nt("designer.hint.import") }}</el-button
        >
        <el-button @click="showImportJsonDialogFlag = false">
          {{ i18nt("designer.hint.cancel") }}</el-button
        >
      </div>
    </el-dialog>
    <!-- 导出json -->
    <el-dialog
      :title="i18nt('designer.toolbar.exportJson')"
      :visible.sync="showExportJsonDialogFlag"
      v-if="showExportJsonDialogFlag"
      :show-close="true"
      class="small-padding-dialog"
      center
      v-dialog-drag
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :destroy-on-close="true"
    >
      <code-editor
        :mode="'json'"
        :readonly="true"
        v-model="jsonContent"
      ></code-editor>
      <div slot="footer" class="dialog-footer">
        <el-button
          type="primary"
          class="copy-json-btn"
          :data-clipboard-text="jsonRawContent"
          @click="copyFormJson"
        >
          {{ i18nt("designer.hint.copyJson") }}</el-button
        >
        <el-button @click="saveFormJson">{{
          i18nt("designer.hint.saveFormJson")
        }}</el-button>
        <el-button type="" @click="showExportJsonDialogFlag = false">
          {{ i18nt("designer.hint.closePreview") }}</el-button
        >
      </div>
    </el-dialog>
  </el-container>
</template>

<script>
import WidgetPanel from "./widget-panel/index";
import ToolbarPanel from "./toolbar-panel/index";
import SettingPanel from "./setting-panel/index";
import VFormWidget from "./form-widget/index";
import { createDesigner } from "@/components/form-designer/designer";
import {
  addWindowResizeHandler,
  deepClone,
  getQueryParam,
  getAllContainerWidgets,
  getAllFieldWidgets,
  traverseAllWidgets,
  generateId,
  copyToClipboard,
} from "@/utils/util";
import { MOCK_CASE_URL, VARIANT_FORM_VERSION } from "@/utils/config";
import i18n, { changeLocale } from "@/utils/i18n";
import axios from "axios";
import SvgIcon from "@/components/svg-icon/index";

export default {
  name: "VFormDesigner",
  componentName: "VFormDesigner",
  mixins: [i18n],
  components: {
    SvgIcon,
    WidgetPanel,
    ToolbarPanel,
    SettingPanel,
    VFormWidget,
  },
  props: {
    /* 后端字段列表API */
    fieldListApi: {
      type: Object,
      default: null,
    },

    /* 禁止显示的组件名称数组 */
    bannedWidgets: {
      type: Array,
      default: () => [],
    },

    designerConfig: {
      type: Object,
      default: () => {
        return {
          languageMenu: true, //是否显示语言切换菜单
          externalLink: true, //是否显示GitHub、文档等外部链接
          formTemplates: false, //是否显示表单模板
          eventCollapse: true, //是否显示组件事件属性折叠面板
          widgetNameReadonly: false, //禁止修改组件名称

          clearDesignerButton: true, //是否显示清空设计器按钮
          previewFormButton: true, //是否显示预览表单按钮
          importJsonButton: true, //是否显示导入JSON按钮
          exportJsonButton: true, //是否显示导出JSON器按钮
          exportCodeButton: true, //是否显示导出代码按钮
          generateSFCButton: true, //是否显示生成SFC按钮

          toolbarMaxWidth: 450, //设计器工具按钮栏最大宽度（单位像素）
          toolbarMinWidth: 300, //设计器工具按钮栏最小宽度（单位像素）

          presetCssCode: "", //设计器预设CSS样式代码

          resetFormJson: false, //是否在设计器初始化时将表单内容重置为空
        };
      },
    },

    /* 全局数据源变量 */
    globalDsv: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      vFormVersion: VARIANT_FORM_VERSION,
      curLangName: "",
      curLocale: "",

      vsCodeFlag: false,
      caseName: "",

      // docUrl: "https://www.vform666.com/document3.html",
      // gitUrl: "https://github.com/vform666/variant-form3-vite",
      // chatUrl: "https://www.vform666.com/pages/chat-group/",
      // subScribeUrl: "https://www.vform666.com/pages/pro/",

      scrollerHeight: 0,

      designer: createDesigner(this),

      fieldList: [],
      fullscreen: false, //是否全屏
      showImportJsonDialogFlag: false,
          showExportJsonDialogFlag: false,
    };
  },
  provide() {
    return {
      serverFieldList: this.fieldList,
      getDesignerConfig: () => this.designerConfig,
      getBannedWidgets: () => this.bannedWidgets,
    };
  },
  created() {
    this.vsCodeFlag = getQueryParam("vscode") == 1;
    this.caseName = getQueryParam("case");
  },
  mounted() {
    this.initLocale();

    this.scrollerHeight = window.innerHeight - 56 - 36 + "px";
    addWindowResizeHandler(() => {
      this.$nextTick(() => {
        this.scrollerHeight = window.innerHeight - 56 - 36 + "px";
      });
    });

    this.loadCase();
    this.loadFieldListFromServer();
  },
  methods: {
    testEEH(eventName, eventParams) {
      console.log("test", eventName);
      console.log("test222222", eventParams);
    },
    copyFormJson(e) {
      copyToClipboard(
        this.jsonRawContent,
        e,
        this.$message,
        this.i18nt("designer.hint.copyJsonSuccess"),
        this.i18nt("designer.hint.copyJsonFail")
      );
    },

    saveFormJson() {
      this.saveAsFile(this.jsonContent, `vform${generateId()}.json`);
    },
    showToolButton(configName) {
      if (this.designerConfig[configName] === undefined) {
        return true;
      }

      return !!this.designerConfig[configName];
    },

    importJson() {
      this.importTemplate = JSON.stringify(
        this.designer.getImportTemplate(),
        null,
        "  "
      );
      this.showImportJsonDialogFlag = true;
    },

    doJsonImport() {
      try {
        let importObj = JSON.parse(this.importTemplate);
        this.designer.loadFormJson(importObj);

        this.showImportJsonDialogFlag = false;
        this.$message.success(this.i18nt("designer.hint.importJsonSuccess"));

        this.designer.emitHistoryChange();

        this.designer.emitEvent("form-json-imported", []);
      } catch (ex) {
        this.$message.error(ex + "");
      }
    },

    exportJson() {
      let widgetList = deepClone(this.designer.widgetList);
      let formConfig = deepClone(this.designer.formConfig);
      this.jsonContent = JSON.stringify({ widgetList, formConfig }, null, "  ");
      this.jsonRawContent = JSON.stringify({ widgetList, formConfig });
      this.showExportJsonDialogFlag = true;
    },
  //全屏
  handleFullScreen() {
      let element = document.documentElement;
        // 判断是否已经是全屏
        // 如果是全屏，退出
        if (this.fullscreen) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitCancelFullScreen) {
                document.webkitCancelFullScreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
            console.log('已还原！');
        } else {    // 否则，进入全屏
            if (element.requestFullscreen) {
                element.requestFullscreen();
            } else if (element.webkitRequestFullScreen) {
                element.webkitRequestFullScreen();
            } else if (element.mozRequestFullScreen) {
                element.mozRequestFullScreen();
            } else if (element.msRequestFullscreen) {
                // IE11
                element.msRequestFullscreen();
            }
            console.log('已全屏！');
        }
        // 改变当前全屏状态
        this.fullscreen = !this.fullscreen;
     
    },
    showLink(configName) {
      if (this.designerConfig[configName] === undefined) {
        return true;
      }

      return !!this.designerConfig[configName];
    },

    openHome() {
      // if (!!this.vsCodeFlag) {
      //   const msgObj = {
      //     cmd: "openUrl",
      //     data: {
      //       url: "https://www.vform666.com/",
      //     },
      //   };
      //   window.parent.postMessage(msgObj, "*");
      // }
    },

    openUrl(event, url) {
      if (!!this.vsCodeFlag) {
        const msgObj = {
          cmd: "openUrl",
          data: {
            url,
          },
        };
        window.parent.postMessage(msgObj, "*");
      } else {
        let aDom = event.currentTarget;
        aDom.href = url;
        //window.open(url, '_blank') //直接打开新窗口，会被浏览器拦截
      }
    },

    loadCase() {
      if (!this.caseName) {
        return;
      }

      // axios
      //   .get(MOCK_CASE_URL + this.caseName + ".txt")
      //   .then((res) => {
      //     if (!!res.data.code) {
      //       this.$message.error(this.i18nt("designer.hint.sampleLoadedFail"));
      //       return;
      //     }

          this.setFormJson(res.data);
          this.$message.success(
            this.i18nt("designer.hint.sampleLoadedSuccess")
          );
      //   })
      //   .catch((error) => {
      //     this.$message.error(
      //       this.i18nt("designer.hint.sampleLoadedFail") + ":" + error
      //     );
      //   });
    },

    initLocale() {
      this.curLocale = localStorage.getItem("v_form_locale");
      if (!!this.vsCodeFlag) {
        this.curLocale = this.curLocale || "en-US";
      } else {
        this.curLocale = this.curLocale || "zh-CN";
      }
      this.curLangName = this.i18nt("application." + this.curLocale);
      this.changeLanguage(this.curLocale);
    },

    loadFieldListFromServer() {
      if (!this.fieldListApi) {
        return;
      }

      let headers = this.fieldListApi.headers || {};
      axios
        .get(this.fieldListApi.URL, { headers: headers })
        .then((res) => {
          let labelKey = this.fieldListApi.labelKey || "label";
          let nameKey = this.fieldListApi.nameKey || "name";

          this.fieldList.splice(0, this.fieldList.length); //清空已有
          res.data.forEach((fieldItem) => {
            this.fieldList.push({
              label: fieldItem[labelKey],
              name: fieldItem[nameKey],
            });
          });
        })
        .catch((error) => {
          this.$message.error(error);
        });
    },

    handleLanguageChanged(command) {
      this.changeLanguage(command);
      this.curLangName = this.i18nt("application." + command);
    },

    changeLanguage(langName) {
      changeLocale(langName);
    },

    setFormJson(formJson) {
      let modifiedFlag = false;
      if (!!formJson) {
        if (typeof formJson === "string") {
          modifiedFlag = this.designer.loadFormJson(JSON.parse(formJson));
        } else if (formJson.constructor === Object) {
          modifiedFlag = this.designer.loadFormJson(formJson);
        }

        if (modifiedFlag) {
          this.designer.emitHistoryChange();
        }
      }
    },

    getFormJson() {
      return {
        widgetList: deepClone(this.designer.widgetList),
        formConfig: deepClone(this.designer.formConfig),
      };
    },

    clearDesigner() {
      this.$refs.toolbarRef.clearFormWidget();
    },

    /**
     * 刷新计量采集表单设计器
     */
    refreshDesigner() {
      //this.designer.loadFormJson( this.getFormJson() )  //只有第一次调用生效？？

      let fJson = this.getFormJson();
      this.designer.clearDesigner(true); //不触发历史记录变更
      this.designer.loadFormJson(fJson);
    },

    /**
     * 预览表单
     */
    previewForm() {
      this.$refs.toolbarRef.previewForm();
    },

    /**
     * 导入表单JSON
     */
    importJson() {
      this.$refs.toolbarRef.importJson();
    },

    /**
     * 导出表单JSON
     */
    exportJson() {
      this.$refs.toolbarRef.exportJson();
    },

    /**
     * 导出Vue/HTML代码
     */
    exportCode() {
      this.$refs.toolbarRef.exportCode();
    },

    /**
     * 生成SFC代码
     */
    generateSFC() {
      this.$refs.toolbarRef.generateSFC();
    },

    /**
     * 获取所有字段组件
     * @returns {*[]}
     */
    getFieldWidgets(widgetList = null) {
      return !!widgetList
        ? getAllFieldWidgets(widgetList)
        : getAllFieldWidgets(this.designer.widgetList);
    },

    /**
     * 获取所有容器组件
     * @returns {*[]}
     */
    getContainerWidgets(widgetList = null) {
      return !!widgetList
        ? getAllContainerWidgets(widgetList)
        : getAllContainerWidgets(this.designer.widgetList);
    },

    /**
     * 升级表单json，以补充最新的组件属性
     * @param formJson
     */
    upgradeFormJson(formJson) {
      if (!formJson.widgetList || !formJson.formConfig) {
        this.$message.error("Invalid form json!");
        return;
      }

      traverseAllWidgets(formJson.widgetList, (w) => {
        this.designer.upgradeWidgetConfig(w);
      });
      this.designer.upgradeFormConfig(formJson.formConfig);

      return formJson;
    },

    getWidgetRef(widgetName, showError = false) {
      return this.$refs["formRef"].getWidgetRef(widgetName, showError);
    },

    getSelectedWidgetRef() {
      return this.$refs["formRef"].getSelectedWidgetRef();
    },

    //TODO: 增加更多方法！！
  },
};
</script>

<style lang="scss" scoped>
@import "../../assets/css/variable.scss"; 
.el-container.main-container {
  background: #fff;

  ::v-deep aside {
    /* 防止aside样式被外部样式覆盖！！ */
    margin: 0;
    padding: 0;
    background: inherit;
  }
}
.btn-size {
  background: #eff2f7;
  color: "#272e3e";
  width: 74px !important;
  height: 36px !important;
}
.Bigbtn-size {
  background: #eff2f7;
  color: "#272e3e";
  height: 36px !important;
}
.el-container.full-height {
  height: 100%;
  overflow-y: hidden;
}

.el-container.center-layout-container {
  min-width: 680px;
  border-left: 2px dotted #ebeef5;
  border-right: 2px dotted #ebeef5;
}

.el-header.main-header {
  border-bottom: 2px dotted #ebeef5;
  height: 60px !important;
  line-height: 60px !important;
  min-width: 800px;
}

div.main-title {
  font-size: 18px;
  color: #242424;
  display: flex;
  align-items: center;
  justify-items: center;

  img {
    cursor: pointer;
    width: 36px;
    height: 36px;
  }

  span.bold {
    font-size: 18px;
    color: $colorTheme;
    margin: 0 6px 0 30px;
  }

  span.version-span {
    font-size: 14px;
    color: #101f1c;
    margin-left: 6px;
  }
}

.float-left {
  float: left;
}

.float-right {
  float: right;
}
.el-dropdown-link {
  margin-right: 12px;
  cursor: pointer;
}

div.external-link a {
  font-size: 13px;
  text-decoration: none;
  margin-right: 10px;
  color: #606266;
}

.el-header.toolbar-header {
  font-size: 14px;
  border-bottom: 1px dotted #cccccc;
  height: 42px !important;
  //line-height: 42px !important;
}

.el-aside.side-panel {
  width: 314px !important;
  overflow-y: hidden;
}

.el-main.form-widget-main {
  padding: 0;
  position: relative;
  overflow-x: hidden;
  background: #f0f3f6;
}

.container-scroll-bar {
  ::v-deep .el-scrollbar__wrap,
  ::v-deep .el-scrollbar__view {
    overflow-x: hidden;
  }
}
//保存按钮的样式
.preserve {
  background-color: $colorTheme;
}
.preserve:hover {
  color: $colorTheme !important;
  background-color: #fff;
  border-color: $colorTheme !important;
}
//退出
::v-deep .el-button--small:hover {
  color: $colorTheme;
}
</style>
